package com.smile.cloud.warn.biz;

import cn.hutool.core.date.DateUtil;
import com.smile.cloud.common.base.exception.BizException;
import com.smile.cloud.common.base.result.CommonResult;
import com.smile.cloud.common.base.result.IResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


/**
 * @author LGC
 */
@Aspect
@Slf4j
@Order(2)
@Component
public class BizWarnAspect {


    @Pointcut("@annotation(BizWarn)")
    public void pointcut() {

    }

    @Around(value = "pointcut() && @annotation(bizWarn)")
    public Object doAroundMethod(ProceedingJoinPoint joinPoint, BizWarn bizWarn) throws Throwable {
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        } catch (BizException bizException) {
            // 获取异常栈的首个元素
            StackTraceElement stackTraceElement = bizException.getStackTrace()[0];
            log.error("异常：文件名：{}", stackTraceElement.getFileName());
            log.error("异常：类名：{}", stackTraceElement.getClassName());
            log.error("异常：方法名：{}", stackTraceElement.getMethodName());
            log.error("异常：行数：{}", stackTraceElement.getLineNumber());

            // 异常描述
            String exceptionDesc = bizWarn.desc();
            // 异常消息
            IResultCode resultCode = bizException.getResultCode();

            String msg = "[" + DateUtil.now() + "]" + "业务异常 desc:[" + exceptionDesc + "] code:[" + resultCode.getCode() + "] msg:[" + bizException.getMsg() + "]";
            log.error("异常：{}", msg, bizException);

            // 发送netty
            /*if (bizWarn.send_netty()) {
                //异常指令
                CommandBaseEnum commandBaseEnum = bizWarn.netty_cmd();
                // 萤石异常
                if (enumInterface instanceof MonitorYsResultEnum) {
                    sendNettyMsg(msg, CommandBaseEnum.EXTERNAL_ERROR.getCode(), RabbitBindEnum.NETTY_SERVER_MONITOR_BACK_BIND);
                }
                // 停车
                if (enumInterface instanceof ParkResultEnum) {
                    sendNettyMsg(msg, commandBaseEnum.getCode(), RabbitBindEnum.NETTY_SERVER_PARK_BACK_BIND);
                }
            }*/

            // 发送钉钉
           /* if(bizWarn.dingTalk_handle()){
                try {
                    DingTalkUtil.sendText(msg);
                } catch (Exception e) {
                    log.error("告警信息发送到钉钉异常：{}", msg, e);
                }
            }*/

            // 返回值 特殊 处理
            if (bizWarn.result_handle()) {
                Object newInstance = bizWarn.result_class().newInstance();
                if (newInstance instanceof CommonResult) {
                    CommonResult commonResult = (CommonResult) newInstance;
                    commonResult.setCode(resultCode.getCode());
                    commonResult.setMsg(resultCode.getMsg());
                    return commonResult;
                }
            }
        }
        return proceed;
    }

    @AfterThrowing(pointcut = "pointcut()", throwing = "ex")
    public void afterThrow(JoinPoint joinPoint, Exception ex) throws InstantiationException, IllegalAccessException {
        if (!(ex instanceof BizException)) {
            log.error("afterThrow异常 ：" + joinPoint + "\t" + ex.getMessage());
            StackTraceElement stackTraceElement = ex.getStackTrace()[0];
            log.error("afterThrow异常：文件名：{}", stackTraceElement.getFileName());
            log.error("afterThrow异常：类名：{}", stackTraceElement.getClassName());
            log.error("afterThrow异常：方法名：{}", stackTraceElement.getMethodName());
            log.error("afterThrow异常：行数：{}", stackTraceElement.getLineNumber());


            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            BizWarn bizWarn = method.getAnnotation(BizWarn.class);
            String msg = "[" + DateUtil.now() + "]" + "内部异常 desc:[" + bizWarn.desc() + "] msg[" + ex.getMessage() + "]";
            log.error("afterThrow异常：{}", msg, ex);


            // 发送netty
            /*if (bizWarn.send_netty()) {
                this.sendNettyMsg(msg, CommandBaseEnum.ERROR.getCode(), RabbitBindEnum.NETTY_SERVER_ERROR_BIND);
            }*/

            // 发送钉钉
           /* if(bizWarn.dingTalk_handle()){
                try {
                    DingTalkUtil.sendText(msg);
                } catch (Exception e) {
                    log.error("告警信息发送到钉钉异常：{}", msg, e);
                }
            }*/
        }
    }

//    private <O> void sendNettyMsg(O o, String cmd, RabbitBindEnum rabbitBindEnum) {
//        NettyBaseMessage<O> pushMessage = new NettyBaseMessage<>();
//        pushMessage.setCmd(cmd);
//        pushMessage.setData(o);
//        rabbitUtil.sendNettyMessage(rabbitBindEnum, pushMessage);
//    }

}
